package com.ls.config;

import com.ls.constant.GatewayConstant;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;

import java.time.Duration;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import reactor.core.publisher.Mono;

/**
 * @author liushuai
 * @version 1.0
 * @description: 路由配置 可以拦截请求 对请求作出修改 再路由到其他服务器
 * @date 2021/4/20 下午7:43
 */
@Configuration
public class RoutesConfig {

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 拦截网关端口下 /oauth/token的请求，判断是否有access_token 如果有则设置到redis中
     * 没有则路由到授权服务器
     * @param builder
     * @return
     */
    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        RouteLocatorBuilder.Builder routes = builder.routes();
        routes.route("oauth-server-router", r -> r.path("/oauth/token")
                .filters(f -> f.modifyResponseBody(String.class, String.class,
                        (exchanges, s) -> {
                            // 拿到登录响应值 s
                            JSONObject jsonObject = JSONUtil.parseObj(s);
                            String accessToken = jsonObject.getStr("access_token");
                            if (StringUtils.hasText(accessToken)) {
                                // 登录成功了
                                // 拿到过期时间
                                Long expiresIn = jsonObject.getLong("expires_in");
                                // 存入redis
                                redisTemplate.opsForValue().set(GatewayConstant.TOKEN_JWT_PREFIX + accessToken, "", Duration.ofSeconds(expiresIn));
                            }
                            return Mono.just(s);
                        }))
                .uri("lb://auth-server"));
        return routes.build();
    }
}
